﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace EnerForecast
{
    class Device
    {
        public string Name { get; set; }
        public double MaxLoad { get; set; }
        public int DeviceType { get; set; }
        public double Cost { get; set; }
        public virtual double GetCostByLoadRate(int rate){
            return Cost;
        }
    }

    class ElectricCooling : Device
    {
        public ElectricCooling(int type,int envitemp=30)
        {

            DeviceType = type; 
            Temperature = envitemp;
            if (type == 1)
            {
                Name = "600RT制冷机组";
                MaxLoad = 2150;
                Device fp = new Device();
                fp.Name = "冷冻水泵 259m³/h";
                fp.Cost = 16.7;
                Device cp = new Device();
                cp.Name = "冷却水泵 417m³/h";
                cp.Cost = 51;
                FreezePump = fp;
                CoolingPump = cp;                
            }
            else if (type == 2)
            {
                Name = "1100RT制冷机组";
                MaxLoad = 3900;
                Device fp = new Device();
                fp.Name = "冷冻水泵 470m³/h";
                fp.Cost = 33;
                Device cp = new Device();
                cp.Name = "冷却水泵 759m³/h";
                cp.Cost = 78;
                FreezePump = fp;
                CoolingPump = cp;
            }
            else
            {
                Name = "冰蓄冷空调工况机组";
                MaxLoad = 6329;
                Device fp = new Device();
                fp.Name = "冷冻水泵参考冰蓄冷机组乙二醇泵";
                fp.Cost = 0;
                Device cp = new Device();
                cp.Name = "冷却泵1250m³/h";
                cp.Cost = 148;
                FreezePump = fp;
                CoolingPump = cp; 
            }
        }

        public override double GetCostByLoadRate(int rate)
        {
            int temprature = Temperature;
            double cost=0;
            ForeCastDataSetTableAdapters.tb_deviceCOPTableAdapter deviAdapter = new ForeCastDataSetTableAdapters.tb_deviceCOPTableAdapter();
            ForeCastDataSet.tb_deviceCOPDataTable deviDatatable = new ForeCastDataSet.tb_deviceCOPDataTable();

            if (rate >0&&rate<=20)
            {
                deviDatatable = deviAdapter.GetDataByPCTnTYPE("20", DeviceType);
                ForeCastDataSet.tb_deviceCOPRow deviDatarow = (ForeCastDataSet.tb_deviceCOPRow)deviDatatable.Rows[0];
                cost = MathHelper.CalculateCubicEquation(deviDatarow.a, deviDatarow.b, deviDatarow.c, deviDatarow.d, temprature);
                cost = cost * rate / 20;
            }
            else if(rate>20&&rate<100)
            {
                int temp = rate / 10;
                int Upercent = temp * 10 + 10;
                int Lpercent = temp * 10;
                double Ucost, Lcost;
                //取得上下线最高最低负荷率
                deviDatatable = deviAdapter.GetDataByPCTnTYPE(Upercent.ToString(), DeviceType);
                ForeCastDataSet.tb_deviceCOPRow deviDatarow = (ForeCastDataSet.tb_deviceCOPRow)deviDatatable.Rows[0];
                Ucost = MathHelper.CalculateCubicEquation(deviDatarow.a, deviDatarow.b, deviDatarow.c, deviDatarow.d, temprature);
                deviDatatable = deviAdapter.GetDataByPCTnTYPE(Lpercent.ToString(), DeviceType);
                deviDatarow = (ForeCastDataSet.tb_deviceCOPRow)deviDatatable.Rows[0];
                Lcost = MathHelper.CalculateCubicEquation(deviDatarow.a, deviDatarow.b, deviDatarow.c, deviDatarow.d, temprature);
                //中间值线性求得
                temp = rate % 10;
                cost = (temp * Ucost + (10 - temp) * Lcost) / 10;
            }
            else if (rate >= 100)
            {
                deviDatatable = deviAdapter.GetDataByPCTnTYPE("100", DeviceType);
                ForeCastDataSet.tb_deviceCOPRow deviDatarow = (ForeCastDataSet.tb_deviceCOPRow)deviDatatable.Rows[0];
                cost = MathHelper.CalculateCubicEquation(deviDatarow.a, deviDatarow.b, deviDatarow.c, deviDatarow.d, temprature);
                cost = cost * rate / 100;
            }

            //if (rate > 0&&DeviceType!=3)
            //{
                cost += FreezePump.GetCostByLoadRate(rate) + CoolingPump.GetCostByLoadRate(rate);//开启了一对一定频水泵
            //    //空调工况除外
            //}
            
            return cost;          
        }

        private Device FreezePump;//一对一
        private Device CoolingPump;//一对一
        private int Temperature;
    }

    class IceStorage : Device
    {
        public IceStorage(int envitemp = 30) {
            Temperature = envitemp;
            Name = "冰蓄冷机组";
            Device fp = new Device();
            fp.Name = "冷冻水一次泵";
            fp.MaxLoad = 7350;
            fp.Cost = 122;
            Freeze1stPump = fp;
            Device bp = new Device();
            bp.Name = "板换二次测水泵";
            bp.Cost = 72.5;
            bp.MaxLoad = 6125;
            Board2ndPump = bp;
            Device cp = new Device();
            cp.Cost = 148;
            cp.Name = "冷却泵1250m³/h";
            CoolingPump = cp;
            ElectricCooling ec = new ElectricCooling(3);//空调机组
            AirCondition = ec;
            IceTank it = new IceTank();
            SingleIceTank = it;
        }
        public new double GetCostByLoadRate(int rate,int numAircondition=0,int numiceTank=3)//供冷工况下
            //按开启的机组数量和负载率返回能耗
        {
            double cost = SingleIceTank.GetCostByLoadRate(rate) * numiceTank + AirCondition.GetCostByLoadRate(rate) * numAircondition;
            double tempLoad = (rate / 100) * (SingleIceTank.MaxLoad * numiceTank + AirCondition.MaxLoad * numAircondition);
            int num1st = (int)(tempLoad / Freeze1stPump.MaxLoad) + 1;
            int num2nd = (int)(tempLoad / Board2ndPump.MaxLoad) + 1;
            cost += num1st * Freeze1stPump.Cost + num2nd * Board2ndPump.Cost;
            return cost;
        }
        public void IceConsume(double icingLoad)
        {
            SingleIceTank.ICESTORAGE -= icingLoad / 3;
        }
        private int Temperature;
        private Device Freeze1stPump;//三用一备
        private Device Board2ndPump;//三用一备
        private Device CoolingPump;//三用一备 一对一用于蓄冰工况
        private IceTank SingleIceTank;//三个
        private ElectricCooling AirCondition;//三个

    }
    class IceTank : Device
    {
        public IceTank(int envitemp = 30)
        {
            Temperature = envitemp;
            Name = "蓄冰槽";
            MaxLoad = 4100;
            ICESTORAGE = 30900;

            ForeCastDataSetTableAdapters.tb_deviceCOPTableAdapter deviAdapter = new ForeCastDataSetTableAdapters.tb_deviceCOPTableAdapter();
            ForeCastDataSet.tb_deviceCOPDataTable deviDatatable = new ForeCastDataSet.tb_deviceCOPDataTable();
            deviDatatable = deviAdapter.GetDataByPCTnTYPE("100", 3);
            ForeCastDataSet.tb_deviceCOPRow deviDatarow = (ForeCastDataSet.tb_deviceCOPRow)deviDatatable.Rows[0];
            icingLoad = MathHelper.CalculateCubicEquation(deviDatarow.a, deviDatarow.b, deviDatarow.c, deviDatarow.d, Temperature);
            
            deviDatatable = deviAdapter.GetDataByPCTnTYPE("100", 4);
            deviDatarow = (ForeCastDataSet.tb_deviceCOPRow)deviDatatable.Rows[0];
            icingCop= MathHelper.CalculateCubicEquation(deviDatarow.a, deviDatarow.b, deviDatarow.c, deviDatarow.d, Temperature);

        }

        public double IcingCost
        {
            get
            {
                return icingLoad / icingCop;
            }
        }
        public double IcingLoad
        {
            get
            {
                return icingLoad;
            }
            set
            {
                icingLoad = value;
            }
        }
        public double IcingCOP
        {
            get
            {
                return icingCop;
            }
            set
            {
                icingCop = value;
            }
        }
        public  double ICESTORAGE{get;set;}
        private double icingLoad, icingCop;
        private double Temperature;
    }
    class HeatPump : Device
    {
     public   HeatPump()
        {
            Name = "地缘热泵";
            MaxLoad = 311;
            Cost = 0;
        }
    }
    class LBPump : Device {

        public LBPump()
        {
            Name = "溴化锂";
            MaxLoad = 1680;
            Cost = 0;
        }
    }
}
